-- UISkyActivityCombatInfo
-- Create By chendh Aug/16/2016
-- 天空活动战斗信息界面

-- UISkyActivityCombatInfo继承自Layer
UISkyActivityCombatInfo = class("UISkyActivityCombatInfo", function()
    return cc.Layer:create();
end);

function UISkyActivityCombatInfo.create(activityId, combatId)
    return UISkyActivityCombatInfo.new(activityId, combatId);
end

-- 内部函数声明
local offsetY = 0;
local fixWidth = 0;

-- 奖励格最大行数和列数
local MAX_GRID_ROW    = 2;
local MIN_GRID_COLUMN = 4;

-- 浮岛资源路径
local SKY_ISLAND_RES_PATH = "images/ui/sky_city/sky_island/";

-- 构造函数
function UISkyActivityCombatInfo:ctor(activityId, combatId)
    -- 初始化
    self:setName("UISkyActivityCombatInfo");
    -- 复用飞艇信息页面
    local node = cc.CSLoader:createNode("layout/sky_city/IslandInfo.csb");
    self:addChild(node);
    self.node = node;

    -- 详细信息
    self.activityId = activityId;
    self.combatId = combatId;

    local bonusNode = findChildByName(self.node, "BT2/desc_node/bonus_node");
    self.scrollView = findChildByName(bonusNode, "bonus_panel");

    -- 重绘
    self:redraw();

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 播放信息出现效果
    local detailNode = findChildByName(self.node, "CT/detail_node");
    playAirShipInfoEffect(detailNode);

    -- 播放准心特效
    -- local reticleNode = findChildByName(self.node, "CT/reticle_node");
    playReticleEffect(self.node);

    -- 标题和描述在中间浮现
    self:comformCenterEffect();

    -- 适配
    self:resize();
end

-- 分析浮岛信息
function UISkyActivityCombatInfo:initData()
    local combatId = self.combatId;
    local combatConfig = SkyActivityM.queryCombat(combatId);
    local combatDbase = combatConfig["combat_dbase"];

    -- 标题
    local title = combatConfig["name"];

    -- 四维信息
    local ability = table.deepcopy(combatDbase);
    -- 总战力
    local fightAbility = combatConfig["fight_ability"];

    -- BOSS编号
    local monsterId = combatConfig["class_id"];

    -- 总积分
    local totalScore    = combatConfig["score"];
    local totalMedal    = combatConfig["medal"];
    local activityData  = SkyActivityM.getActivityData(self.activityId);
    local combat        = activityData["combat"] or {};
    local combatData    = combat[combatId] or {};
    local minHp         = combatData["min_hp"] or fightAbility;
    local curScore      = combatData["score"] or 0;

    local data = {};
    data = {
        ["title"]           = title,
        ["monsterId"]       = monsterId,
        ["desc"]            = combatConfig["desc"],
        ["ability"]         = ability,
        ["fightAbility"]    = fightAbility,
        ["totalScore"]      = totalScore,
        ["curScore"]        = curScore,
        ["totalMedal"]      = totalMedal,
        ["failEggsId"]      = combatData["fail_eggs"],
        ["bonus"]           = { {2, "score", totalScore - curScore},
                                {2, "medal", totalMedal} },
    };
    return data;
end

-- 适配
function UISkyActivityCombatInfo:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");
    AlignM.fitToScreen(node, "bg2");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    AlignM.alignToTopCenter(node, "Top");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
    AlignM.alignToBottomCenter(node, "BT2");
end

-- 重绘界面
function UISkyActivityCombatInfo:redraw()
    -- 构造分析浮岛详细信息
    local data = self:initData();
    self.data = data;

    -- 上调位置节点
    local moveNodes = {};

    -- 显示标题
    local titleLabel = findChildByName(self.node, "Top/title/text");
    titleLabel:setString(data.title);
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 绘制图标
    local monsterId = data["monsterId"];
    local displayNode;

    if type(monsterId) == "number" then
        local modelId = PetM.query(monsterId, "default_model");
        local petInfo = PetM.queryModel(modelId);
        local iconPath = getHeroIconPath(petInfo["icon"]);
        local iconImg = ccui.ImageView:create();
        local monsterNode = cc.Node:create();
        local icon = findChildByName(self.node, "CT/airship");
        displayNode = icon;

        icon:addChild(iconImg);
        icon:addChild(monsterNode);

        local display;

        local shapeId = SkyActivityM.queryCombat(self.combatId, "shape_id");
        if shapeId > 0 then
            local shapeInfo = ShapeChangeM.query(shapeId);
            iconPath = getHeroIconPath(shapeInfo["icon"]);
            local animation = shapeInfo["animation"];
            display = createShapeChangeMode(shapeId, iconImg, animation, monsterNode,
                shapeInfo["model_scale"], iconPath, shapeInfo["offset_x"], shapeInfo["offset_y"] + 40);

        else
            display = createHeroModel(modelId, iconImg, monsterNode,
                petInfo["model_scale"], iconPath, petInfo["offset_x"], petInfo["offset_y"] + 40);
        end
        monsterNode.display = display;
        icon:setScale(1);
    elseif type(monsterId) == "table" then
        local combatNum = #monsterId;
        local opacity = {255, 220, 220, 200, 200, 170};
        local scale   = {0.8, 0.5, 0.5, 0.4, 0.4, 0.4};
        local showNum = math.min(combatNum, 6);
        local hideBossNode = findChildByName(self.node, "CT/hide_boss");
        displayNode = hideBossNode;

        for index=1, showNum do
            repeat
                local node = findChildByName(hideBossNode, "combat" .. index);

                if not node then
                    break;
                end

                node:removeAllChildren();
                local monsterIcon = ccui.ImageView:create();
                local monsterNode = cc.Node:create();
                node:addChild(monsterIcon);
                node:addChild(monsterNode);

                -- 创建怪物模型
                local id = monsterId[index];
                local modelId = PetM.query(id, "default_model");
                local petInfo = PetM.queryModel(modelId);
                local iconPath = getHeroIconPath(petInfo["icon"]);

                local display = createHeroModel(modelId, monsterIcon, monsterNode,
                    petInfo["model_scale"], iconPath, petInfo["offset_x"], petInfo["offset_y"]);
                monsterNode.display = display;
                monsterNode:setScale(scale[index]);
                display:setOpacity(opacity[index]);
            until true
        end
    end

    -- 平台
    local platformImg = findChildByName(self.node, "CT/platform");
    local platformEffect = findChildByName(self.node, "CT/platform_effect");
    platformImg:setVisible(true);
    platformEffect:setVisible(true);
    platformEffect:setOpacity(255);

    -- 记录初始坐标
    if not platformImg.intPosY then
        platformImg.intPosY = platformImg:getPositionY();
    end
    if not platformEffect.intPosY then
        platformEffect.intPosY = platformEffect:getPositionY();
    end
    if not displayNode.intPosY then
        displayNode.intPosY = displayNode:getPositionY();
    end
    -- 恢复初始坐标
    platformImg:setPositionY(platformImg.intPosY);
    platformEffect:setPositionY(platformEffect.intPosY);
    displayNode:setPositionY(displayNode.intPosY);
    -- 停止所有的action
    platformImg:stopAllActions();
    platformEffect:stopAllActions();
    displayNode:stopAllActions();
    -- 开始上下浮动
    playFluctuateAnima(platformImg, 2, 8);
    playFluctuateAnima(platformEffect, 2, 8);
    playFluctuateAnima(displayNode, 2, 8);

    -- 平台下方光效的淡入淡出
    local fadeIn = cc.FadeIn:create(2);
    local fadeOut = cc.FadeOut:create(2);
    local scaleUp = cc.ScaleTo:create(2, 1.1);
    local scaleDown = cc.ScaleTo:create(2, 1);
    platformEffect:runAction(cc.RepeatForever:create(cc.Sequence:create(cc.Spawn:create(fadeOut, scaleDown), cc.Spawn:create(fadeIn, scaleUp))));

    -- 四维信息
    local ability = data.ability;

    local detailNode = findChildByName(self.node, "CT/detail_node");
    -- 火力
    local attribLabel = findChildByName(detailNode, "fire_node/attrib");
    local valueLabel = findChildByName(detailNode, "fire_node/value");

    self:setSystemTextStyle(attribLabel);
    self:setSystemTextStyle(valueLabel);

    attribLabel:setString(getLocStr("airship_fire"));
    valueLabel:setString(ability.fire);

    -- 装甲
    attribLabel = findChildByName(detailNode, "armor_node/attrib");
    valueLabel = findChildByName(detailNode, "armor_node/value");

    self:setSystemTextStyle(attribLabel);
    self:setSystemTextStyle(valueLabel);

    attribLabel:setString(getLocStr("airship_armor"));
    valueLabel:setString(ability.armor);

    -- 机动
    attribLabel = findChildByName(detailNode, "speed_node/attrib");
    valueLabel = findChildByName(detailNode, "speed_node/value");

    self:setSystemTextStyle(attribLabel);
    self:setSystemTextStyle(valueLabel);

    attribLabel:setString(getLocStr("airship_speed"));
    valueLabel:setString(ability.speed);

    -- 幸运
    attribLabel = findChildByName(detailNode, "luck_node/attrib");
    valueLabel = findChildByName(detailNode, "luck_node/value");

    self:setSystemTextStyle(attribLabel);
    self:setSystemTextStyle(valueLabel);

    attribLabel:setString(getLocStr("airship_luck"));
    valueLabel:setString(ability.luck);

    -- 总战力
    attribLabel = findChildByName(detailNode, "ability_node/attrib");
    valueLabel = findChildByName(detailNode, "ability_node/value");

    self:setSystemTextStyle(attribLabel);
    self:setSystemTextStyle(valueLabel);

    attribLabel:setString(getLocStr("fight_ability_2"));

    -- 逗号分段战力
    valueLabel:setString(thousandNum(data.fightAbility));

    -- 需要显示国籍
    local nation = findChildByName(self.node, "Top/title/nation");
    local campNode = findChildByName(detailNode, "camp_node");
    nation:setVisible(false);
    campNode:setVisible(false);

    self:redrawDesc();

    -- 绘制奖励
    self:redrawBonus();

    -- 显示符石框
    local stoneNode = findChildByName(self.node, "BT2/stone");
    local failEggsId = data["failEggsId"];

    if not failEggsId or failEggsId <= 0 then
        stoneNode:removeAllChildren();
        return;
    end

    local stoneId = SkyActivityM.queryFailEggs(failEggsId, "stone_id");
    -- 显示符石框
    local stoneNode = findChildByName(self.node, "BT2/stone");
    -- 没有增加的时候才增加
    if not stoneNode.iconNode then
        local itemNode = cc.CSLoader:createNode("layout/sky_city/SkyCityStoneItem.csb");
        local iconNode = findChildByName(itemNode, "icon");
        local bgNode = findChildByName(itemNode, "bg");
        local iconName = ItemM.query(stoneId, "icon");
        iconNode:loadTexture(getItemIconPath(iconName));

        local function onClickStone(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                require "game/ui/form/workshop/UIItemDesc"

                local uiItemDesc = UIItemDesc.create(stoneId);
                UIMgr:getCurrentScene():addForm(uiItemDesc);
            end
        end

        bgNode:addTouchEventListener(onClickStone);
        itemNode:setScale(0.8);
        stoneNode:addChild(itemNode);
    end
end

-- 清空所有的奖励格
function UISkyActivityCombatInfo:clearAllGrid()
    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();
end

-- 绘制奖励
function UISkyActivityCombatInfo:redrawBonus()
    local bonusNode = findChildByName(self.node, "BT2/desc_node/bonus_node");
    bonusNode:setVisible(true);
    local panel = findChildByName(bonusNode, "bonus_panel");

    -- 收集信息
    local goodsList = self.data["bonus"] or {};
    local totalGridCount = #goodsList;

    if not goodsList or #goodsList == 0 then
        cclog("收集信息失败。");
        self:clearAllGrid();
        return;
    end

    -- 初始化格子
    self:initGrids(totalGridCount);

    -- 显示奖励信息
    local totalGoodsCount = #goodsList;

    if totalGoodsCount < 4 then
        totalGoodsCount = 4;
    end

    for i = 1, totalGridCount do
        local grid          = self.scrollView:getChildByName("item" .. i);
        local goodsBg       = grid:getChildByName("bg");
        local buyImg        = grid:getChildByName("buy");
        local starNode      = grid:getChildByName("stars");
        local numLabel      = grid:getChildByName("num_label");
        local countLabel    = grid:getChildByName("num");
        local iconImg       = grid:getChildByName("icon");

        countLabel:setVisible(true);
        numLabel:setVisible(false);
        buyImg:setVisible(false);

        if i <= totalGoodsCount and type(goodsList[i]) == "table" then
            grid:setVisible(true);

            local classId = goodsList[i][2];
            local count   = goodsList[i][3];

            -- 显示数量
            TextStyleM.setTextStyle(countLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -2);
            if count > 1 then
                -- 需要显示数量
                countLabel:setString(changeNumType(count));
            else
                countLabel:setVisible(false);
            end

            -- 显示商品图标
            local goodsIcon;
            if classId == "score" then
                goodsIcon = getLargeAttribIconPath("score");
            elseif classId == "medal" then
                goodsIcon = getLargeAttribIconPath("medal");
            end

            iconImg:loadTexture(goodsIcon);

            -- 注册点击事件
            self:clickShowDesc(grid, goodsList[i]);
        else
            -- 多余格子置灰白
            iconImg:setVisible(false);
            setGrayTransMode(goodsBg, true);
        end
    end
end

-- 初始化奖励格子
function UISkyActivityCombatInfo:initGrids(gridCount)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 图标间距(横向)
    local wGap = -5;

    -- 图标间距(纵向)
    local hGap = 10;

    -- 图标宽度
    local iconWidth = 127;

    -- 图片高度
    local iconHeight = 110;

    local topHGap  = 10;
    local bottomHGap  = 0;
    local leftWGap = 5;

    -- 总数
    local totalCount = gridCount;

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/sky_city/SkyStoreItem.csb");
    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param maxRowNum     最大行数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留白
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    -- @param initHandle    格子初始化委托
    -- @param schedulerId   定时器id
    initScrollGridsVertical(self, self.scrollView, itemNode,
        totalCount, MAX_GRID_ROW, MIN_GRID_COLUMN, wGap, hGap,
        iconWidth, iconHeight, topHGap, bottomHGap, leftWGap);

    for _, child in ipairs(self.scrollView.rows) do
        child:setScale(0.88);
    end
end

-- 点击图标处理
function UISkyActivityCombatInfo:clickShowDesc(node, bonus)
    -- 点击处理
    local bg = findChildByName(node, "bg");
    bg:setTouchEnabled(true);
    bg:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("workshop_material");

            local classId   = bonus[2];
            local cound     = bonus[3];
            local extra;
            UIMgr:getCurrentScene():removeFormByName("UIItemDesc");
            if classId == "score" then
                extra = string.format(getLocStr("scroe_detail"), self.data["title"], self.data["curScore"], self.data["totalScore"]);
            elseif classId == "medal" then
                local remainTime = ActivityM.getRemainRunningTime(self.activityId);
                local timeDesc = remainingTimeDesc(remainTime);
                extra = string.format(getLocStr("medal_detail"), timeDesc);
            end

            -- 显示奖励描述信息
            local uiItemDesc = UIItemDesc.create(classId, nil, {["extra"] = extra});
            UIMgr:getCurrentScene():addForm(uiItemDesc);
        end
    end);
end


-- 注册事件处理回调函数
function UISkyActivityCombatInfo:registerEventCallback()
    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            EventMgr.removeAll("UISkyActivityCombatInfo");
        elseif eventType == "enter" then

        end
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UISkyActivityCombatInfo", event.FOCUS_CHANGED, function(para)
        -- TODO
        if para["get"] == "UISkyActivityCombatInfo" then
            -- 显示战斗和四维
            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_AIRSHIP_SCORE, TOPMENU_FRAME_AIRSHIP_ATTRIB, TOPMENU_FRAME_HEAD_AIRSHIP);

            if type(self.extraData) == "table" then
                -- 显示符石框
                local stoneNode = findChildByName(self.node, "BT2/stone");
                local failEggsId = self.extraData["fail_eggs"];
                local reviveFailReturn = self.extraData["revive_fail_return"];

                self.extraData = nil;
                if failEggsId and failEggsId > 0 then
                    -- 战败彩蛋
                    local templateId = SkyActivityM.queryFailEggs(failEggsId, "diaglue_template");
                    local stoneId = SkyActivityM.queryFailEggs(failEggsId, "stone_id");

                    local function callback()
                        -- 对白结束回调，绘制失败彩蛋的符石

                        -- 显示符石框
                        local stoneNode = findChildByName(self.node, "BT2/stone");
                        -- 没有增加的时候才增加
                        if not stoneNode.iconNode then
                            local itemNode = cc.CSLoader:createNode("layout/sky_city/SkyCityStoneItem.csb");
                            local iconNode = findChildByName(itemNode, "icon");
                            local bgNode = findChildByName(itemNode, "bg");
                            local iconName = ItemM.query(stoneId, "icon");
                            iconNode:loadTexture(getItemIconPath(iconName));

                            local function onClickStone(sender, eventType)
                                if eventType == ccui.TouchEventType.ended then
                                    require "game/ui/form/workshop/UIItemDesc"

                                    local uiItemDesc = UIItemDesc.create(stoneId);
                                    UIMgr:getCurrentScene():addForm(uiItemDesc);
                                end
                            end

                            bgNode:addTouchEventListener(onClickStone);
                            itemNode:setScale(0.8);
                            stoneNode:addChild(itemNode);
                        end
                    end

                    require "game/ui/form/main/UIDialogue";
                    local uiDialog = UIDialogue.create(templateId, callback);
                    UIMgr.getCurrentScene():addForm(uiDialog);
                elseif reviveFailReturn and reviveFailReturn > 0 then
                    stoneNode:removeAllChildren();

                    -- 复活次数满且未击杀怪物，回退一半钻石
                    local function callback()
                        -- 对白结束回调，提示获得钻石
                        showBonusNotifyForm(nil, {{2, "gem", reviveFailReturn}});
                    end

                    require "game/ui/form/main/UIDialogue";
                    local uiDialog = UIDialogue.create("sky_activity_revive_fail", callback);
                    UIMgr.getCurrentScene():addForm(uiDialog);
                    return;
                else
                    stoneNode:removeAllChildren();
                    return;
                end
            end

        elseif para["lose"] == "UISkyActivityCombatInfo" then

        end
    end);

    -- 注册参与活动结果的回调
    EventMgr.register("UISkyActivityCombatInfo", event.SKY_ACTIVITY_RESULT, function(para)
        -- 关闭 "加载中" 界面
        closeCommunicatingForm();

        -- 缓存信息
        local extraData = para["extra_data"];
        self.extraData = extraData;
    end);

    -- 关注玩家属性变化
    EventMgr.register("UISkyActivityCombatInfo", event.USER_INFO_UPDATED, function(para)
        if para == "sky_activity" then
            -- 重绘
            local data = self:initData();
            self.data = data;
            self:redrawBonus();
        end
    end);

    -- 关注活动关闭事件
    EventMgr.register("UISkyActivityCombatInfo", event.ACTIVITY_CLOSE, function(args)
        -- 如果是当前活动关闭了，那么退出界面
        if self.activityId == args["id"] then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UISkyActivityCombatInfo");
        end
    end);

    -- 关注活动变化事件
    EventMgr.register("UISkyActivityCombatInfo", event.ACTIVITY_CHANGE, function(args)
        -- 如果是当前活动变化了，那么退出界面
        if self.activityId == args["id"] then
            if args["status"] == ACTIVITY_STATUS_END or args["status"] == ACTIVITY_STATUS_CLOSE then
                -- 本次活动已结束，无法继续战斗！
                alert(getLocStr("activity_end"));
            else
                -- 怪物已重置！
                alert(getLocStr("sky_activity_combat_reseted"));
            end

            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UISkyActivityCombatInfo");
        end
    end);
end

-- 注册点击事件
function UISkyActivityCombatInfo:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UISkyActivityCombatInfo");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 隐藏建造/出战/翻页按钮
    local btnMake = findChildByName(self.node, "BT/btn_make");
    local btnActived = findChildByName(self.node, "BT/btn_actived");
    local btnNext = findChildByName(self.node, "CT/btn_next");
    local btnLast = findChildByName(self.node, "CT/btn_last");
    local hideNodes = {btnMake, btnActived, btnNext, btnLast};
    for _, node in pairs(hideNodes) do
        node:setVisible(false);
    end

    -- 袭击说明按钮点击事件
    local btnAttack = findChildByName(self.node, "BT/btn_make");
    local function onAttackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("ship_click");

            -- 尝试去袭击
            self:tryToAttack();
        end
    end
    btnAttack:addTouchEventListener(onAttackClick);
    TextStyleM.setTextStyle(btnAttack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnAttack:setTitleText(getLocStr("btn_text_attack"));
    btnAttack:setVisible(true);
end

-- 设置信息的字体
function UISkyActivityCombatInfo:setSystemTextStyle(textLabel)
    textLabel:setFontSize(TextStyleM.TEXT_SIZE_TINY + 2);
    textLabel:setTextColor(TextStyleM.TEXT_COLOR_BRIGHT_BLUE);
    -- TextStyleM.setOutlineStyle(textLabel, 2, TextStyleM.TEXT_COLOR_DARK_BLUE2, true);

    textLabel:setScale(0.85);
end

-- 根据当前抽取到的类型，重绘描述信息
function UISkyActivityCombatInfo:redrawDesc()
    local descNode = findChildByName(self.node, "BT2/desc_node");
    local titleLabel = findChildByName(descNode, "title_label");
    local descLabel = findChildByName(descNode, "desc_label");

    -- 根据规则获得当前描述
    local titleName = self.data["title"];
    local descStr = self.data["desc"];

    local lineCount = 4;
    if isFullWidthLang() then
        lineCount = 3;
    elseif getLang() == "th" then
        lineCount = 1.3;
    end
    local textScale = TextStyleM.getTextScale(descStr, 19 * 2 * lineCount);
    TextStyleM.setTextStyle(titleLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_DARK_RED);
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN, nil, nil, nil, nil, nil, nil, nil, textScale);

    titleLabel:setString(titleName);
    descLabel:setString(descStr);
end

-- 从中间浮现效果
function UISkyActivityCombatInfo:comformCenterEffect()
    local BT2 = findChildByName(self.node, "BT2");
    local Top = findChildByName(self.node, "Top");
    if not BT2 or not Top then
        return;
    end

    local titleNode = findChildByName(Top, "title");
    local descNode = findChildByName(BT2, "desc_node");

    local oldScale = titleNode:getScale();
    local descSale = descNode:getScale();

    -- title
    titleNode:setScale(oldScale * 0.8);
    local scaleUp1 = cc.EaseIn:create(cc.ScaleTo:create(0.2, oldScale * 1.05), 0.4);
    local scaleUp2 = cc.ScaleTo:create(0.05, oldScale);
    titleNode:runAction(cc.Sequence:create(scaleUp1, scaleUp2));

    descNode:setScale(descSale * 0.8);
    local scaleUp3 = cc.EaseIn:create(cc.ScaleTo:create(0.2, descSale * 1.05), 0.4);
    local scaleUp4 = cc.ScaleTo:create(0.05, descSale);
    descNode:runAction(cc.Sequence:create(scaleUp3, scaleUp4));
end

-- 尝试去袭击
function UISkyActivityCombatInfo:tryToAttack()
    local activityId = self.activityId;
    local activityData = SkyActivityM.getActivityData(activityId);
    local status = SkyActivityM.getCombatStatus(self.activityId, self.combatId);

    if status == "lock" then
        alert(SkyActivityM.queryCombat(self.combatId, "condition_tip"));
        return;
    elseif status == "is_die" then
        alert(getLocStr("sky_activity_die_tip"));
        return;
    end

    if type(activityData["times"]) ~= "number" or activityData["times"] <= 0 then
        -- 参与活动次数不足，弹出购买界面
        self:joinTimesLack();
        return;
    end

    local activityInfo = ActivityM.getActivityInfo(self.activityId);
    local combatInfo = activityData["combat"] or {};

    if self.combatId == 7 and activityInfo["end_time"] <= activityInfo["daily_reset_time"] then
        -- 如果是第七场战斗，那么如果当前有触发的地牢彩蛋则弹出提示
        for _, info in pairs(combatInfo) do
            if info["dungeon_eggs"] and not info["dungeon_status"] then
                -- 确定回调
                local function doOk()
                    -- 清除缓存信息
                    self.extraData = nil;
                    -- 发消息给服务器
                    Operation.cmd_join_sc_activity(activityId, {["combat_id"] = self.combatId});
                    -- 显示 "加载中" 界面
                    showCommunicatingForm(getLocStr("loading"));
                end

                confirm2(CONFIRM_TYPE_OK, ActivityM.query(self.activityId, "name"),
                    string.format(getLocStr("sky_activity_combat_tip"), SkyActivityM.queryCombat(self.combatId, "name")), doOk);
                return;
            end
        end
    end

    -- 清除缓存信息
    self.extraData = nil;

    -- 发消息给服务器
    Operation.cmd_join_sc_activity(activityId, {["combat_id"] = self.combatId});

    -- 显示 "加载中" 界面
    showCommunicatingForm(getLocStr("loading"));
end

-- 活动参与次数不足的处理
function UISkyActivityCombatInfo:joinTimesLack()
    local activityId = self.activityId;
    local desc;
    local activityData = SkyActivityM.getActivityData(activityId);
    local cost = FormulaM.invoke("CALC_BUY_ACTIVITY_TIMES_COST", activityId);
    local curTimes = activityData["times"] or 0;
    local bonusTimes = FormulaM.invoke("CALC_BUY_ACTIVITY_TIMES", activityId);
    local maxTimes = SkyActivityM.getMaxTimes(activityId);
    local resultTimes = math.min(maxTimes, curTimes + bonusTimes);

    -- 花费[blue]%d[-]个%s，\n立即恢复[blue]%d[-]点袭击次数！\n[blue]（当前次数%d/%d，恢复后%d/%d）[-]
    desc = string.format(getLocStr("buy_activity_times_desc"), cost[3], ItemM.query(cost[2], "name"), bonusTimes, curTimes, maxTimes, resultTimes, maxTimes);

    local function buyTimes()
        if ItemM.getAmount(ME.user, cost[2]) < cost[3] then
            alert(string.format(getLocStr("item_not_enough2"), ItemM.query(cost[2], "name")));
            return;
        end
        -- 发消息去服务端购买参与次数
        Operation.cmd_buy_activity_times(activityId);
    end

    -- 弹出购买活动次数的提示框
    confirm2(CONFIRM_TYPE_OK, getLocStr("buy_activity_times_title"), desc,
        buyTimes, nil, getLocStr("btn_text_buy"));
end